function mxCellRenderer()
{
	this.shapes = mxUtils.clone(this.defaultShapes);
};
mxCellRenderer.prototype.collapseExpandResource = (mxClient.language != 'none') ? 'collapse-expand' : '';
mxCellRenderer.prototype.shapes = null;
mxCellRenderer.prototype.defaultEdgeShape = mxPolyline;
mxCellRenderer.prototype.defaultVertexShape = mxRectangleShape;
mxCellRenderer.prototype.defaultShapes = {};
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_ARROW] = mxArrow;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_RECTANGLE] = mxRectangleShape;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_ELLIPSE] = mxEllipse;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_DOUBLE_ELLIPSE] = mxDoubleEllipse;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_RHOMBUS] = mxRhombus;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_IMAGE] = mxImageShape;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_LINE] = mxLine;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_LABEL] = mxLabel;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_CYLINDER] = mxCylinder;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_SWIMLANE] = mxSwimlane;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_CONNECTOR] = mxConnector;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_ACTOR] = mxActor;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_CLOUD] = mxCloud;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_TRIANGLE] = mxTriangle;
mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_HEXAGON] = mxHexagon;
mxCellRenderer.prototype.registerShape = function(key, shape)
{
	this.shapes[key] = shape;
};
mxCellRenderer.prototype.initialize = function(state)
{
	var model = state.view.graph.getModel();

	if (state.view.graph.container != null && state.shape == null && state.cell != state.view.currentRoot
		&& (model.isVertex(state.cell) || model.isEdge(state.cell)))
	{
		this.createShape(state);

		if (state.shape != null)
		{
			this.initializeShape(state);

			if (state.view.graph.ordered)
			{
				state.orderChanged = true;
			}
			else if (model.isEdge(state.cell))
			{
				this.orderEdge(state);
			}
			else if (state.view.graph.keepEdgesInForeground && this.firstEdge != null)
			{
				if (this.firstEdge.parentNode == state.shape.node.parentNode)
				{
					this.inserState(state, this.firstEdge);
				}
				else
				{
					this.firstEdge = null;
				}
			}
			state.shape.scale = state.view.scale;
			this.createCellOverlays(state);
			this.installListeners(state);
		}

		var cells = state.view.graph.getSelectionCells();

		if (mxUtils.indexOf(cells, state.cell) >= 0)
		{
			state.doCreateHandler = true;
		}
	}
};
mxCellRenderer.prototype.initializeShape = function(state)
{
	state.shape.init(state.view.getDrawPane());
}
mxCellRenderer.prototype.getPreviousStateInContainer = function(state, container)
{
	var result = null;
	var graph = state.view.graph;
	var model = graph.getModel();
	var child = state.cell;
	var p = model.getParent(child);

	while (p != null && result == null)
	{
		result = this.findPreviousStateInContainer(graph, p, child, container);
		child = p;
		p = model.getParent(child);
	}
	return result;
};
mxCellRenderer.prototype.findPreviousStateInContainer = function(graph, cell, stop, container)
{
	var result = null;
	var model = graph.getModel();

	if (stop != null)
	{
		var start = cell.getIndex(stop);

		for (var i = start - 1; i >= 0 && result == null; i--)
		{
			result = this.findPreviousStateInContainer(graph, model.getChildAt(cell, i), null, container);
		}
	}
	else
	{
		var childCount = model.getChildCount(cell);

		for (var i = childCount - 1; i >= 0 && result == null; i--)
		{
			result = this.findPreviousStateInContainer(graph, model.getChildAt(cell, i), null, container);
		}
	}

	if (result == null)
	{
		result = graph.view.getState(cell);

		if (result != null
			&& (result.shape == null || result.shape.node == null || result.shape.node.parentNode != container))
		{
			result = null;
		}
	}
	return result;
};
mxCellRenderer.prototype.order = function(state)
{
	var container = state.shape.node.parentNode;
	var previous = this.getPreviousStateInContainer(state, container);
	var nextNode = container.firstChild;

	if (previous != null)
	{
		nextNode = previous.shape.node;

		if (previous.text != null && previous.text.node != null && previous.text.node.parentNode == container)
		{
			nextNode = previous.text.node;
		}
		nextNode = nextNode.nextSibling;
	}
	this.insertState(state, nextNode);
};
mxCellRenderer.prototype.orderEdge = function(state)
{
	var view = state.view;
	var model = view.graph.getModel();

	if (view.graph.keepEdgesInForeground)
	{
		var node = state.shape.node;

		if (this.firstEdge == null || this.firstEdge.parentNode == null
			|| this.firstEdge.parentNode != state.shape.node.parentNode)
		{
			this.firstEdge = state.shape.node;
		}
	}
	else if (view.graph.keepEdgesInBackground)
	{
		var node = state.shape.node;
		var parent = node.parentNode;
		var pcell = model.getParent(state.cell);
		var pstate = view.getState(pcell);

		if (pstate != null && pstate.shape != null && pstate.shape.node != null)
		{
			var child = pstate.shape.node.nextSibling;

			if (child != null && child != node)
			{
				this.insertState(state, child);
			}
		}
		else
		{
			var child = parent.firstChild;

			if (child != null && child != node)
			{
				this.insertState(state, child);
			}
		}
	}
};
mxCellRenderer.prototype.insertState = function(state, nextNode)
{
	state.shape.node.parentNode.insertBefore(state.shape.node, nextNode);

	if (state.text != null && state.text.node != null && state.text.node.parentNode == state.shape.node.parentNode)
	{
		state.shape.node.parentNode.insertBefore(state.text.node, state.shape.node.nextSibling);
	}
};
mxCellRenderer.prototype.createShape = function(state)
{
	if (state.style != null)
	{
		var ctor = this.getShapeConstructor(state);
		state.shape = new ctor();
		state.shape.points = state.absolutePoints;
		state.shape.bounds = new mxRectangle(state.x, state.y, state.width, state.height);
		state.shape.dialect = state.view.graph.dialect;
		this.configureShape(state);
	}
};
mxCellRenderer.prototype.getShapeConstructor = function(state)
{
	var key = state.style[mxConstants.STYLE_SHAPE];
	var ctor = (key != null) ? this.shapes[key] : null;

	if (ctor == null)
	{
		ctor=(state.view.graph.getModel().isEdge(state.cell))? this.defaultEdgeShape : this.defaultVertexShape;
	}
	return ctor;
};
mxCellRenderer.prototype.configureShape = function(state)
{
	state.shape.apply(state);
	var image = state.view.graph.getImage(state);

	if (image != null)
	{
		state.shape.image = image;
	}
	var indicator = state.view.graph.getIndicatorColor(state);
	var key = state.view.graph.getIndicatorShape(state);
	var ctor = (key != null) ? this.shapes[key] : null;

	if (indicator != null)
	{
		state.shape.indicatorShape = ctor;
		state.shape.indicatorColor = indicator;
		state.shape.indicatorGradientColor = state.view.graph.getIndicatorGradientColor(state);
	}
	else
	{
		var indicator = state.view.graph.getIndicatorImage(state);

		if (indicator != null)
		{
			state.shape.indicatorImage = indicator;
		}
	}
	this.postConfigureShape(state);
};
mxCellRenderer.prototype.postConfigureShape = function(state)
{
	if (state.shape != null)
	{
		this.resolveColor(state, 'indicatorColor', mxConstants.STYLE_FILLCOLOR);
		this.resolveColor(state, 'indicatorGradientColor', mxConstants.STYLE_GRADIENTCOLOR);
		this.resolveColor(state, 'fill', mxConstants.STYLE_FILLCOLOR);
		this.resolveColor(state, 'stroke', mxConstants.STYLE_STROKECOLOR);
		this.resolveColor(state, 'gradient', mxConstants.STYLE_GRADIENTCOLOR);
	}
};
mxCellRenderer.prototype.resolveColor = function(state, field, key)
{
	var value = state.shape[field];
	var graph = state.view.graph;
	var referenced = null;

	if (value == 'inherit')
	{
		referenced = graph.model.getParent(state.cell);
	}
	else if (value == 'swimlane')
	{
		if (graph.model.getTerminal(state.cell, false) != null)
		{
			referenced = graph.model.getTerminal(state.cell, false);
		}
		else
		{
			referenced = state.cell;
		}
		referenced = graph.getSwimlane(referenced);
		key = graph.swimlaneIndicatorColorAttribute;
	}
	else if (value == 'indicated')
	{
		state.shape[field] = state.shape.indicatorColor;
	}

	if (referenced != null)
	{
		var rstate = graph.getView().getState(referenced);
		state.shape[field] = null;

		if (rstate != null)
		{
			if (rstate.shape != null && field != 'indicatorColor')
			{
				state.shape[field] = rstate.shape[field];
			}
			else
			{
				state.shape[field] = rstate.style[key];
			}
		}
	}
};
mxCellRenderer.prototype.getLabelValue = function(state)
{
	var graph = state.view.graph;
	var value = graph.getLabel(state.cell);

	if (!graph.isHtmlLabel(state.cell) && (value != null && !mxUtils.isNode(value)) && mxClient.IS_IE)
	{
		value = mxUtils.htmlEntities(value, false);
	}
	return value;
};
mxCellRenderer.prototype.isLabelEvent = function(state, evt)
{
	return true;
};
mxCellRenderer.prototype.createLabel = function(state)
{
	var self = this;
	var graph = state.view.graph;
	var isEdge = graph.getModel().isEdge(state.cell);

	if (state.style[mxConstants.STYLE_FONTSIZE] > 0 || state.style[mxConstants.STYLE_FONTSIZE] == null)
	{
		var value = this.getLabelValue(state);

		if (value == null || value.length == 0)
		{
			return;
		}
		var isForceHtml = (graph.isHtmlLabel(state.cell) || (value != null && mxUtils.isNode(value)))
			&& graph.dialect == mxConstants.DIALECT_SVG;
		var isRotate = state.style[mxConstants.STYLE_HORIZONTAL] == false;
		state.text = new mxText(value, new mxRectangle(), state.style[mxConstants.STYLE_ALIGN],
			graph.getVerticalAlign(state), state.style[mxConstants.STYLE_FONTCOLOR],
			state.style[mxConstants.STYLE_FONTFAMILY], state.style[mxConstants.STYLE_FONTSIZE],
			state.style[mxConstants.STYLE_FONTSTYLE], state.style[mxConstants.STYLE_SPACING],
			state.style[mxConstants.STYLE_SPACING_TOP], state.style[mxConstants.STYLE_SPACING_RIGHT],
			state.style[mxConstants.STYLE_SPACING_BOTTOM], state.style[mxConstants.STYLE_SPACING_LEFT], isRotate,
			state.style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR], state.style[mxConstants.STYLE_LABEL_BORDERCOLOR],
			isEdge, isEdge || isForceHtml, graph.isWrapping(state.cell), graph.isLabelClipped(state.cell));
		state.text.opacity = state.style[mxConstants.STYLE_TEXT_OPACITY];
		state.text.dialect = (isForceHtml) ? mxConstants.DIALECT_STRICTHTML : state.view.graph.dialect;
		this.initializeLabel(state);
		var cursor = graph.getCursorForCell(state.cell);

		if (cursor != null || (graph.isEnabled() && graph.isCellMovable(state.cell)))
		{
			state.text.node.style.cursor = cursor || 'move';
		}
		mxEvent.addListener(state.text.node, 'mousedown', function(evt)
		{
			if (self.isLabelEvent(state, evt))
			{
				var handle = null;

				if (graph.getModel().isEdge(state.cell) && graph.isCellSelected(state.cell))
				{
					handle = mxEvent.LABEL_HANDLE;
				}
				graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state, handle));
			}
		});
		mxEvent.addListener(state.text.node, 'mousemove', function(evt)
		{
			if (self.isLabelEvent(state, evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, state));
			}
		});
		mxEvent.addListener(state.text.node, 'mouseup', function(evt)
		{
			if (self.isLabelEvent(state, evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, state));
			}
		});
		mxEvent.addListener(state.text.node, 'dblclick', function(evt)
		{
			if (self.isLabelEvent(state, evt))
			{
				graph.dblClick(evt, state.cell);
				mxEvent.consume(evt);
			}
		});
	}
};
mxCellRenderer.prototype.initializeLabel = function(state)
{
	var graph = state.view.graph;

	if (state.text.dialect != mxConstants.DIALECT_SVG)
	{
		if (graph.dialect == mxConstants.DIALECT_SVG)
		{
			var node = graph.container;
			var overflow = node.style.overflow;
			state.text.isAbsolute = true;
			state.text.init(node);
			node.style.overflow = overflow;
			return;
		}
		else if (mxUtils.isVml(state.view.getDrawPane()))
		{
			if (state.shape.label != null)
			{
				state.text.init(state.shape.label);
			}
			else
			{
				state.text.init(state.shape.node);
			}
			return;
		}
	}
	state.text.init(state.view.getDrawPane());
	state.text.isAbsolute = true;

	if (state.shape != null && state.text != null)
	{
		state.shape.node.parentNode.insertBefore(state.text.node, state.shape.node.nextSibling);
	}
};
mxCellRenderer.prototype.createCellOverlays = function(state)
{
	var graph = state.view.graph;
	var overlays = graph.getCellOverlays(state.cell);

	if (overlays != null)
	{
		state.overlays = [];

		for (var i = 0; i < overlays.length; i++)
		{
			var tmp = new mxImageShape(new mxRectangle(), overlays[i].image.src);
			tmp.dialect = state.view.graph.dialect;
			tmp.init(state.view.getOverlayPane());
			tmp.node.style.cursor = 'help';
			this.installCellOverlayListeners(state, overlays[i], tmp);
			state.overlays.push(tmp);
		}
	}
};
mxCellRenderer.prototype.installCellOverlayListeners = function(state, overlay, shape)
{
	var graph = state.view.graph;
	mxEvent.addListener(shape.node, 'click', function(evt)
	{
		overlay.fireEvent(mxEvent.CLICK, new mxEventObject(
		[
			evt,
			state.cell
		]));
	});

	mxEvent.addListener(shape.node, 'mousedown', function(evt)
	{
		mxEvent.consume(evt);
	});
	mxEvent.addListener(shape.node, 'mousemove', function(evt)
	{
		graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, state, overlay, overlay.tooltip));
	});
};
mxCellRenderer.prototype.createControl = function(state)
{
	var graph = state.view.graph;
	var image = graph.getFoldingImage(state);

	if (graph.foldingEnabled && image != null)
	{
		if (state.control == null)
		{
			var b = new mxRectangle(0, 0, image.width, image.height);
			state.control = new mxImageShape(b, image.src);
			state.control.dialect = state.view.graph.dialect;

			var isForceHtml = (graph.isHtmlLabel(state.cell) && state.view.graph.dialect == mxConstants.DIALECT_SVG)
				|| mxClient.IS_GC || mxClient.IS_SF;

			if (isForceHtml)
			{
				state.control.dialect = mxConstants.DIALECT_PREFERHTML;
				state.control.init(graph.container);
				state.control.node.style.zIndex = 1;
			}
			else
			{
				state.control.init(state.view.getOverlayPane());
			}
			var node = state.control.innerNode || state.control.node;
			var tip = this.collapseExpandResource;
			tip = mxResources.get(tip) || tip;

			if (graph.isEnabled())
			{
				node.style.cursor = 'pointer';
			}
			mxEvent.addListener(node, 'click', function(evt)
			{
				if (graph.isEnabled())
				{
					var collapse = !graph.isCellCollapsed(state.cell);
					graph.foldCells(collapse, false, [state.cell]);
					mxEvent.consume(evt);
				}
			});
			mxEvent.addListener(node, 'mousedown', function(evt)
			{
				graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
				mxEvent.consume(evt);
			});
			mxEvent.addListener(node, 'mousemove', function(evt)
			{
				graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, state, null, tip));
			});
		}
	}
	else if (state.control != null)
	{
		state.control.destroy();
		state.control = null;
	}
};
mxCellRenderer.prototype.isShapeEvent = function(state, evt)
{
	return true;
};
mxCellRenderer.prototype.installListeners = function(state)
{
	var self = this;
	var graph = state.view.graph;

	if (graph.dialect == mxConstants.DIALECT_SVG)
	{
		var events = 'all';

		if (graph.getModel().isEdge(state.cell) && state.shape.stroke != null && state.shape.fill == null)
		{
			events = 'visibleStroke';
		}

		if (state.shape.innerNode != null)
		{
			state.shape.innerNode.setAttribute('pointer-events', events);
		}
		else
		{
			state.shape.node.setAttribute('pointer-events', events);
		}
	}
	var cursor = graph.getCursorForCell(state.cell);

	if (cursor != null || graph.isEnabled())
	{
		if (cursor == null)
		{
			if (graph.getModel().isEdge(state.cell))
			{
				cursor = 'pointer';
			}
			else if (graph.isCellMovable(state.cell))
			{
				cursor = 'move';
			}
		}

		if (state.shape.innerNode != null && !graph.getModel().isEdge(state.cell))
		{
			state.shape.innerNode.style.cursor = cursor;
		}
		else
		{
			state.shape.node.style.cursor = cursor;
		}
	}
	mxEvent.addListener(state.shape.node, 'mousedown', function(evt)
	{
		if (self.isShapeEvent(state, evt))
		{
			graph.fireMouseEvent(mxEvent.MOUSE_DOWN,
				new mxMouseEvent(evt, (state.shape != null && mxEvent.getSource(evt) == state.shape.content)
					? null : state));
		}
	});
	mxEvent.addListener(state.shape.node, 'mousemove', function(evt)
	{
		if (self.isShapeEvent(state, evt))
		{
			graph.fireMouseEvent(mxEvent.MOUSE_MOVE,
				new mxMouseEvent(evt, (state.shape != null && mxEvent.getSource(evt) == state.shape.content)
					? null : state));
		}
	});
	mxEvent.addListener(state.shape.node, 'mouseup', function(evt)
	{
		if (self.isShapeEvent(state, evt))
		{
			graph.fireMouseEvent(mxEvent.MOUSE_UP,
				new mxMouseEvent(evt, (state.shape != null && mxEvent.getSource(evt) == state.shape.content)
					? null : state));
		}
	});
	mxEvent.addListener(state.shape.node, 'dblclick', function(evt)
	{
		if (self.isShapeEvent(state, evt))
		{
			graph.dblClick(evt, (state.shape != null && mxEvent.getSource(evt) == state.shape.content)
				? null : state.cell);
			mxEvent.consume(evt);
		}
	});
};
mxCellRenderer.prototype.redrawLabel = function(state)
{
	var value = this.getLabelValue(state);

	if (state.text == null && value != null && value.length > 0)
	{
		this.createLabel(state);
	}
	else if (state.text != null && (value == null || value.length == 0))
	{
		state.text.destroy();
		state.text = null;
	}

	if (state.text != null)
	{
		var graph = state.view.graph;
		var wrapping = graph.isWrapping(state.cell);
		var clipping = graph.isLabelClipped(state.cell);
		var bounds = this.getLabelBounds(state);

		if (state.text.value != value || state.text.isWrapping != wrapping || state.text.isClipping != clipping
			|| state.text.scale != state.view.scale || !state.text.bounds.equals(bounds))
		{
			state.text.value = value;
			state.text.bounds = bounds;
			state.text.scale = state.view.scale;
			state.text.isWrapping = wrapping;
			state.text.isClipping = clipping;
			state.text.redraw();
		}
	}
};
mxCellRenderer.prototype.getLabelBounds = function(state)
{
	var graph = state.view.graph;
	var isEdge = graph.getModel().isEdge(state.cell);
	var bounds = new mxRectangle(state.absoluteOffset.x, state.absoluteOffset.y);

	if (!isEdge)
	{
		bounds.x += state.shape.bounds.x;
		bounds.y += state.shape.bounds.y;
		bounds.width = Math.max(1, state.shape.bounds.width);
		bounds.height = Math.max(1, state.shape.bounds.height);
		var isRotate = state.style[mxConstants.STYLE_HORIZONTAL] == false;

		if (graph.isSwimlane(state.cell))
		{
			var scale = graph.view.scale;
			var height = (parseInt(state.style[mxConstants.STYLE_STARTSIZE]) || 0) * scale;

			if (isRotate)
			{
				bounds.width = height;
			}
			else
			{
				bounds.height = height;
			}
		}
	}
	return bounds;
};
mxCellRenderer.prototype.redrawCellOverlays = function(state)
{
	var overlays = state.view.graph.getCellOverlays(state.cell);
	var oldCount = (state.overlays != null) ? state.overlays.length : 0;
	var newCount = (overlays != null) ? overlays.length : 0;

	if (oldCount != newCount)
	{
		if (oldCount > 0)
		{
			for (var i = 0; i < state.overlays.length; i++)
			{
				state.overlays[i].destroy();
			}
			state.overlays = null;
		}

		if (newCount > 0)
		{
			this.createCellOverlays(state);
		}
	}

	if (state.overlays != null)
	{
		for (var i = 0; i < overlays.length; i++)
		{
			var bounds = overlays[i].getBounds(state);

			if (state.overlays[i].bounds == null || state.overlays[i].scale != state.view.scale
				|| !state.overlays[i].bounds.equals(bounds))
			{
				state.overlays[i].bounds = bounds;
				state.overlays[i].scale = state.view.scale;
				state.overlays[i].redraw();
			}
		}
	}
};
mxCellRenderer.prototype.redrawControl = function(state)
{
	if (state.control != null)
	{
		var bounds = this.getControlBounds(state);
		var s = state.view.scale;

		if (state.control.scale != s || !state.control.bounds.equals(bounds))
		{
			state.control.bounds = bounds;
			state.control.scale = s;
			state.control.redraw();
		}
	}
};
mxCellRenderer.prototype.getControlBounds = function(state)
{
	if (state.control != null)
	{
		var oldScale = state.control.scale;
		var w = state.control.bounds.width / oldScale;
		var h = state.control.bounds.height / oldScale;
		var s = state.view.scale;
		return (state.view.graph.getModel().isEdge(state.cell)) ? new mxRectangle(
			state.x + state.width / 2 - w / 2 * s, state.y + state.height / 2 - h / 2 * s, w * s, h * s)
			: new mxRectangle(state.x + w / 2 * s, state.y + h / 2 * s, w * s, h * s);
	}
	return null;
};
mxCellRenderer.prototype.redraw = function(state)
{
	if (state.shape != null)
	{
		var model = state.view.graph.getModel();
		var isEdge = model.isEdge(state.cell);
		var reconfigure = false;
		this.createControl(state);

		if (state.shape.bounds == null || state.shape.scale != state.view.scale
			|| !state.shape.bounds.equals(state) || !mxUtils.equalPoints(state.shape.points, state.absolutePoints))
		{
			if (state.absolutePoints != null)
			{
				state.shape.points = state.absolutePoints.slice();
			}
			else
			{
				state.shape.points = null;
			}
			state.shape.bounds = new mxRectangle(state.x, state.y, state.width, state.height);
			state.shape.scale = state.view.scale;
			state.shape.redraw();
		}
		this.redrawLabel(state);
		this.redrawCellOverlays(state);
		this.redrawControl(state);
		if (state.orderChanged && state.view.graph.ordered)
		{
			this.order(state);
			reconfigure = true;
		}
		delete state.orderChanged;

		if (!mxUtils.equalEntries(state.shape.style, state.style))
		{
			state.shape.apply(state);
			reconfigure = true;
		}

		if (reconfigure)
		{
			this.configureShape(state);
			state.shape.reconfigure();
		}
	}

	if (state.doCreateHandler)
	{
		delete state.doCreateHandler;
		state.view.graph.createHandler(state);
	}

	if (state.view.graph.hasHandler(state))
	{
		state.view.graph.redrawHandler(state);
	}
};
mxCellRenderer.prototype.destroy = function(state)
{
	if (state.shape != null)
	{
		if (state.text != null)
		{
			state.text.destroy();
			state.text = null;
		}

		if (state.overlays != null)
		{
			for (var i = 0; i < state.overlays.length; i++)
			{
				state.overlays[i].destroy();
			}
			state.overlays = null;
		}

		if (state.control != null)
		{
			state.control.destroy();
			state.control = null;
		}
		state.shape.destroy();
		state.shape = null;
	}
};